<template>
  <Temp @close="close" :show-clear="false">
    <div class="mark">
      <div class="mark-draw">
        <div
          class="mark-draw-item"
          v-for="item in markTypeList"
          :key="item.icon"
          @click="handleModeChange(item.icon)"
        >
          <Icon
            :title="item.title"
            :name="item.icon"
            :font-size="item.iconSize"
          />
          <span
            :class="
              currentMode === item.icon ? 'active' : ''
            "
            >{{ item.title }}</span
          >
        </div>
      </div>
      <Search v-model="keyword" @input="onSearchChange" />
      <!--      <el-tabs stretch v-model="typeName">-->
      <!--        <el-tab-pane label="点" name="point">-->
      <!--          <el-scrollbar style="flex: 1">-->
      <!--            <div class="mark-list">-->
      <!--              <div-->
      <!--                class="mark-list-item"-->
      <!--                v-for="(item, index) in shownMarkerList"-->
      <!--                :key="item.pkid"-->
      <!--                @click="handleMarkClick(item, index)"-->
      <!--              >-->
      <!--                <el-image-->
      <!--                  :src="-->
      <!--                    require('@/assets/img/icon_close.png')-->
      <!--                  "-->
      <!--                  @click.stop="-->
      <!--                    handleMarkDelete(item, index)-->
      <!--                  "-->
      <!--                />-->
      <!--                <div class="mark-list-item-head">-->
      <!--                  <Icon-->
      <!--                    :title="getDrawItemTitle(item.type)"-->
      <!--                    :name="getDrawItemName(item.type)"-->
      <!--                    :font-size="-->
      <!--                      getDrawItemIconSize(item.type)-->
      <!--                    "-->
      <!--                  />-->
      <!--                  <span>{{ item.name }}</span>-->
      <!--                </div>-->
      <!--                <span class="description">{{-->
      <!--                  item.remark-->
      <!--                }}</span>-->
      <!--              </div>-->
      <!--            </div>-->
      <!--            <div class="load-more" v-if="!loadMoreDisabled">-->
      <!--              <el-button-->
      <!--                size="mini"-->
      <!--                type="text"-->
      <!--                :loading="isLoadingMore"-->
      <!--                @click="getMarkerList(true)"-->
      <!--                >加载更多</el-button-->
      <!--              >-->
      <!--            </div>-->
      <!--          </el-scrollbar>-->
      <!--        </el-tab-pane>-->
      <!--        <el-tab-pane label="线" name="line">-->
      <!--          <el-scrollbar style="flex: 1">-->
      <!--            <div class="mark-list">-->
      <!--              <div-->
      <!--                class="mark-list-item"-->
      <!--                v-for="(item, index) in shownMarkerList"-->
      <!--                :key="item.pkid"-->
      <!--                @click="handleMarkClick(item, index)"-->
      <!--              >-->
      <!--                <el-image-->
      <!--                  :src="-->
      <!--                    require('@/assets/img/icon_close.png')-->
      <!--                  "-->
      <!--                  @click.stop="-->
      <!--                    handleMarkDelete(item, index)-->
      <!--                  "-->
      <!--                />-->
      <!--                <div class="mark-list-item-head">-->
      <!--                  <Icon-->
      <!--                    :title="getDrawItemTitle(item.type)"-->
      <!--                    :name="getDrawItemName(item.type)"-->
      <!--                    :font-size="-->
      <!--                      getDrawItemIconSize(item.type)-->
      <!--                    "-->
      <!--                  />-->
      <!--                  <span>{{ item.name }}</span>-->
      <!--                </div>-->
      <!--                <span class="description">{{-->
      <!--                  item.remark-->
      <!--                }}</span>-->
      <!--              </div>-->
      <!--            </div>-->
      <!--            <div class="load-more" v-if="!loadMoreDisabled">-->
      <!--              <el-button-->
      <!--                size="mini"-->
      <!--                type="text"-->
      <!--                :loading="isLoadingMore"-->
      <!--                @click="getMarkerList(true)"-->
      <!--                >加载更多</el-button-->
      <!--              >-->
      <!--            </div>-->
      <!--          </el-scrollbar>-->
      <!--        </el-tab-pane>-->
      <!--        <el-tab-pane label="面" name="region">-->
      <!--          <el-scrollbar style="flex: 1">-->
      <!--            <div class="mark-list">-->
      <!--              <div-->
      <!--                class="mark-list-item"-->
      <!--                v-for="(item, index) in shownMarkerList"-->
      <!--                :key="item.pkid"-->
      <!--                @click="handleMarkClick(item, index)"-->
      <!--              >-->
      <!--                <el-image-->
      <!--                  :src="-->
      <!--                    require('@/assets/img/icon_close.png')-->
      <!--                  "-->
      <!--                  @click.stop="-->
      <!--                    handleMarkDelete(item, index)-->
      <!--                  "-->
      <!--                />-->
      <!--                <div class="mark-list-item-head">-->
      <!--                  <Icon-->
      <!--                    :title="getDrawItemTitle(item.type)"-->
      <!--                    :name="getDrawItemName(item.type)"-->
      <!--                    :font-size="-->
      <!--                      getDrawItemIconSize(item.type)-->
      <!--                    "-->
      <!--                  />-->
      <!--                  <span>{{ item.name }}</span>-->
      <!--                </div>-->
      <!--                <span class="description">{{-->
      <!--                  item.remark-->
      <!--                }}</span>-->
      <!--              </div>-->
      <!--            </div>-->
      <!--            <div class="load-more" v-if="!loadMoreDisabled">-->
      <!--              <el-button-->
      <!--                size="mini"-->
      <!--                type="text"-->
      <!--                :loading="isLoadingMore"-->
      <!--                @click="getMarkerList(true)"-->
      <!--                >加载更多</el-button-->
      <!--              >-->
      <!--            </div>-->
      <!--          </el-scrollbar>-->
      <!--        </el-tab-pane>-->
      <!--      </el-tabs>-->
      <el-scrollbar style="flex: 1">
        <div class="mark-list">
          <div
            class="mark-list-item"
            v-for="(item, index) in markList"
            :key="item.pkid"
            @click="handleMarkClick(item, index)"
          >
            <el-image
              :src="require('@/assets/img/icon_close.png')"
              @click.stop="handleMarkDelete(item, index)"
            />
            <div class="mark-list-item-head">
              <Icon
                :title="getDrawItemTitle(item.type)"
                :name="getDrawItemName(item.type)"
                :font-size="getDrawItemIconSize(item.type)"
              />
              <span>{{ item.name }}</span>
            </div>
            <span class="description">{{
              item.remark
            }}</span>
          </div>
        </div>
      </el-scrollbar>
      <el-pagination
        small
        layout="->, prev, pager, next"
        :page-size="pageSize"
        :total="total"
        @current-change="pageChange"
      >
      </el-pagination>
    </div>

    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="600px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      append-to-body
      @close="onDialogClose"
    >
      <el-form
        ref="formRef"
        label-position="left"
        label-width="80px"
        :model="formModal"
        :rules="formRules"
      >
        <el-form-item
          :label="`${currentModeName}名称：`"
          prop="name"
        >
          <el-input
            v-model="formModal.name"
            :placeholder="`请输入${currentModeName}名称`"
          ></el-input>
        </el-form-item>
        <el-form-item label="描述：" prop="description">
          <el-input
            v-model="formModal.description"
            type="textarea"
            rows="3"
            :placeholder="`请对该${currentModeName}进行描述`"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleFormConfirm"
          >确定</el-button
        >
        <el-button @click="handleFormCancel"
          >取消</el-button
        >
      </div>
    </el-dialog>
  </Temp>
</template>

<script>
import Temp from '../temp'
import Icon from '@/components/icon'
import { getAction } from '@/utils/helper'
import Search from '@/components/search'
import togeojson from '@mapbox/togeojson'
import {
  addMarker,
  getMarkers,
  deleteMarker,
  updateMarker
} from '@/api/marker'

const mapViewer = {}
const mark = {}
let drawnEntity = null
const labelLayer = new Cesium.CustomDataSource('labelLayer')

export default {
  name: 'Mark',
  components: {
    Temp,
    Icon,
    Search
  },
  inject: ['viewerId'],
  data() {
    return {
      keyword: '',
      // typeName: 'point',
      typeName: '',
      pageIndex: 1,
      pageSize: 6,
      total: 0,
      isLoadingMore: false,
      loadMoreDisabled: true,
      currentMode: '',
      currentModeName: '',
      isNew: false,
      dialogVisible: false,
      selectedMark: null,
      formModal: {
        name: '',
        description: ''
      },
      formRules: {
        name: [
          {
            required: true,
            message: '请输入名称',
            trigger: 'blur'
          }
        ]
      },
      markTypeList: [
        {
          icon: 'dian',
          title: '绘点',
          iconSize: 12
        },
        {
          icon: 'xian',
          title: '绘线',
          iconSize: 16
        },
        {
          icon: 'mian',
          title: '绘面',
          iconSize: 16
        }
      ],
      markList: [],
      geojsonMap: new Map(),
      labelEntities: new Map(),
      handler: null
    }
  },
  async created() {
    const { toolManager, viewer } = await getAction(
      this.viewerId
    )
    mapViewer[this.viewerId] = viewer
    mapViewer[this.viewerId].dataSources.add(labelLayer)
    mark[this.viewerId] = toolManager.mark
    // this.getMarkerList(false)
    this.getMarkerList()

    this.handler = new Cesium.ScreenSpaceEventHandler(
      viewer.scene.canvas
    )
    this.handler.setInputAction((movement) => {
      const pick = viewer.scene.pick(movement.position)
      // console.log('pick', pick)
      // console.log('geojsonMap', this.geojsonMap)
      if (pick && pick.id) {
        this.geojsonMap.forEach((value, key) => {
          if (
            value.entities.values.indexOf(pick.id) !== -1
          ) {
            console.log('found it')
            const thatOne = this.markList.find(
              (item) => item.pkid === key
            )
            if (thatOne) {
              switch (thatOne.type) {
                case 'point':
                  this.currentModeName = '点'
                  break
                case 'line':
                  this.currentModeName = '线'
                  break
                case 'region':
                  this.currentModeName = '面'
                  break
                default:
                  this.currentModeName = ''
                  break
              }
              this.dialogVisible = true
              this.isNew = false
              this.formModal.name = thatOne.name
              this.formModal.description = thatOne.remark
              this.selectedMark = thatOne
            }
          }
        })
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  },
  beforeDestroy() {
    if (this.handler) {
      this.handler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_CLICK
      )
    }
    this.geojsonMap.forEach((item) => {
      mapViewer[this.viewerId].dataSources.remove(item)
    })
    this.labelEntities.forEach((item) => {
      labelLayer.entities.remove(item)
    })
    mapViewer[this.viewerId].dataSources.remove(labelLayer)
  },
  methods: {
    close() {
      this.labelEntities.forEach((item) => {
        labelLayer.entities.remove(item)
      })
      this.$emit('close')
    },
    getDrawItemTitle(type) {
      switch (type) {
        case 'point':
          return '点'
        case 'line':
          return '线'
        case 'region':
          return '面'
        default:
          return '未知'
      }
    },
    getDrawItemName(type) {
      switch (type) {
        case 'point':
          return 'dian'
        case 'line':
          return 'xian'
        case 'region':
          return 'mian'
        default:
          return 'fanwei'
      }
    },
    getDrawItemIconSize(type) {
      switch (type) {
        case 'point':
          return 12
        default:
          return 16
      }
    },

    /**
     * 获取标注列表数据
     */
    getMarkerList() {
      getMarkers({
        pageIndex: this.pageIndex,
        pageSize: this.pageSize,
        type: this.typeName,
        name: this.keyword
      })
        .then((res) => {
          if (res.success) {
            this.total = res.data.count
            if (res.data && res.data.list) {
              this.markList = res.data.list
            } else {
              this.markList = []
            }
          } else {
            this.$message.error(res.message || '请求失败')
          }
        })
        .catch((err) => {
          console.error(err)
          this.$message.error('请求错误')
        })
    },
    handleModeChange(mode) {
      if (this.currentMode === mode) {
        this.currentMode = ''
      } else {
        this.currentMode = mode
      }
    },
    handleMarkClick(item, index) {
      if (this.geojsonMap.get(item.pkid)) {
        mapViewer[this.viewerId].flyTo(
          this.geojsonMap.get(item.pkid)
        )
      } else {
        const geojson = JSON.parse(item.geojson)
        this.loadGeojson(geojson, item.name, item.pkid)
        mapViewer[this.viewerId].flyTo(
          this.geojsonMap.get(item.pkid)
        )
      }
    },
    handleMarkDelete(item, index) {
      this.$confirm(
        '此操作将永久删除该标注，是否继续?',
        '提示',
        {
          confirmButtonText: '删除',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
        .then(() => {
          deleteMarker(item.pkid).then((res) => {
            if (res.success) {
              if (this.geojsonMap.get(item.pkid)) {
                mapViewer[this.viewerId].dataSources.remove(
                  this.geojsonMap.get(item.pkid)
                )
                labelLayer.entities.remove(
                  this.labelEntities.get(item.pkid)
                )
              }
              this.$message.success(res.data || '删除成功')
              this.getMarkerList(false)
            } else {
              this.$message.error(res.message || '删除失败')
            }
          })
        })
        .catch(() => {
          console.log('取消删除')
        })
    },
    showDialog(entity, isNew) {
      this.isNew = isNew
      this.dialogVisible = true
      drawnEntity = entity
    },
    handleFormConfirm() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          if (this.isNew) {
            let entity
            switch (this.currentMode) {
              case 'dian':
                entity = new Cesium.Entity({
                  name: this.formModal.name,
                  show: true,
                  position: drawnEntity.position,
                  point: {
                    color: Cesium.Color.RED,
                    pixelSize: 5,
                    outlineColor: Cesium.Color.WHITE,
                    outlineWidth: 2,
                    heightReference:
                      Cesium.HeightReference.CLAMP_TO_GROUND
                  },
                  classificationType:
                    Cesium.ClassificationType.BOTH
                })
                break
              case 'xian':
                entity = new Cesium.Entity({
                  name: this.formModal.name,
                  polyline: {
                    positions: drawnEntity.positions,
                    width: 2,
                    material: Cesium.Color.YELLOW
                  },
                  classificationType:
                    Cesium.ClassificationType.BOTH
                })
                break
              case 'mian':
                entity = new Cesium.Entity({
                  name: this.formModal.name,
                  polygon: {
                    hierarchy: drawnEntity.positions,
                    height: 0,
                    material:
                      Cesium.Color.YELLOW.withAlpha(0.5),
                    outline: true,
                    outlineColor: Cesium.Color.YELLOW
                  },
                  classificationType:
                    Cesium.ClassificationType.BOTH
                })
                break
              default:
                break
            }
            if (entity) {
              const entities = new Cesium.EntityCollection()
              entities.add(entity)
              Cesium.exportKml({ entities: entities }).then(
                (e) => {
                  const kml =
                    new DOMParser().parseFromString(
                      e.kml,
                      'text/xml'
                    )
                  const geojson = togeojson.kml(kml)
                  geojson.features.forEach((item) => {
                    item.properties = {}
                  })
                  // console.log('geojson string', JSON.stringify(geojson))
                  addMarker({
                    geojson: JSON.stringify(geojson),
                    remark: this.formModal.description,
                    type:
                      this.currentMode === 'dian'
                        ? 'point'
                        : this.currentMode === 'xian'
                        ? 'line'
                        : 'region',
                    name: this.formModal.name
                  }).then((res) => {
                    if (res.success) {
                      this.$message.success('添加成功')
                      this.dialogVisible = false
                      this.loadGeojson(
                        geojson,
                        this.formModal.name,
                        res.data
                      )
                      this.getMarkerList(false)
                    } else {
                      this.$message.error(
                        res.message || '添加失败'
                      )
                    }
                  })
                }
              )
            }
          } else {
            updateMarker(this.selectedMark.pkid, {
              geojson: this.selectedMark.geojson,
              remark: this.formModal.description,
              type: this.selectedMark.type,
              name: this.formModal.name
            }).then((res) => {
              if (res.success) {
                this.$message.success('修改成功')
                this.selectedMark.name = this.formModal.name
                this.selectedMark.remark =
                  this.formModal.description
                mapViewer[this.viewerId].dataSources.remove(
                  this.geojsonMap.get(
                    this.selectedMark.pkid
                  )
                )
                labelLayer.entities.remove(
                  this.labelEntities.get(
                    this.selectedMark.pkid
                  )
                )
                this.geojsonMap.delete(
                  this.selectedMark.pkid
                )
                this.loadGeojson(
                  JSON.parse(this.selectedMark.geojson),
                  this.formModal.name,
                  this.selectedMark.pkid
                )
                this.dialogVisible = false
              } else {
                this.$message.error(
                  res.message || '修改失败'
                )
              }
            })
          }
        }
      })
    },

    handleFormCancel() {
      this.dialogVisible = false
    },

    loadGeojson(geojson, name, pkid) {
      console.log('geojson', geojson)
      switch (geojson.features[0].geometry.type) {
        case 'Point':
          Cesium.GeoJsonDataSource.load(geojson, {
            markerSize: 15,
            markerColor: Cesium.Color.YELLOW,
            clampToGround: true
          }).then((dataSource) => {
            const entities = dataSource.entities.values
            console.log('dataSource entities', entities)
            entities[0].point = {
              color: Cesium.Color.YELLOW,
              pixelSize: 10,
              outlineColor: Cesium.Color.WHITE,
              outlineWidth: 2,
              heightReference:
                Cesium.HeightReference.CLAMP_TO_GROUND
            }
            const labelEntity = new Cesium.Entity()
            labelEntity.position = entities[0].position
            labelEntity.label = {
              text: name || '',
              show: true,
              showBackground: true,
              font: '16px',
              horizontalOrigin:
                Cesium.HorizontalOrigin.LEFT,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              pixelOffset: new Cesium.Cartesian2(-20, -40),
              heightReference:
                Cesium.HeightReference.CLAMP_TO_GROUND
            }
            mapViewer[this.viewerId].dataSources.add(
              dataSource
            )
            this.geojsonMap.set(pkid, dataSource)
            labelLayer.entities.add(labelEntity)
            this.labelEntities.set(pkid, labelEntity)
          })
          break
        case 'LineString':
          Cesium.GeoJsonDataSource.load(geojson, {
            clampToGround: true
          }).then((dataSource) => {
            const entities = dataSource.entities.values
            console.log('dataSource entities', entities)
            entities[0].polyline.width = 6
            const labelEntity = new Cesium.Entity()
            labelEntity.position =
              entities[0].polyline.positions.getValue()[0]
            labelEntity.label = {
              text: name || '',
              show: true,
              showBackground: true,
              font: '16px',
              horizontalOrigin:
                Cesium.HorizontalOrigin.LEFT,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              pixelOffset: new Cesium.Cartesian2(-20, -40),
              heightReference:
                Cesium.HeightReference.CLAMP_TO_GROUND
            }
            mapViewer[this.viewerId].dataSources.add(
              dataSource
            )
            this.geojsonMap.set(pkid, dataSource)
            labelLayer.entities.add(labelEntity)
            this.labelEntities.set(pkid, labelEntity)
          })
          break
        case 'Polygon':
          Cesium.GeoJsonDataSource.load(geojson, {
            clampToGround: true
          }).then((dataSource) => {
            const entities = dataSource.entities.values
            console.log('dataSource entities', entities)
            entities[0].polygon.extrudedHeight = 0.1
            entities[0].polygon.material =
              Cesium.Color.YELLOW.withAlpha(0.5)
            entities[0].polygon.outline = true
            entities[0].polygon.outlineColor =
              Cesium.Color.WHITE
            entities[0].polygon.outlineWidth = 2
            // entities[0].polygon.perPositionHeight = new Cesium.ConstantProperty(true)
            const labelEntity = new Cesium.Entity()
            labelEntity.position =
              entities[0].polygon.hierarchy.getValue().positions[0]
            labelEntity.label = {
              text: name || '',
              show: true,
              showBackground: true,
              font: '16px',
              horizontalOrigin:
                Cesium.HorizontalOrigin.LEFT,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              pixelOffset: new Cesium.Cartesian2(-20, -40),
              heightReference:
                Cesium.HeightReference.CLAMP_TO_GROUND
            }
            mapViewer[this.viewerId].dataSources.add(
              dataSource
            )
            this.geojsonMap.set(pkid, dataSource)
            labelLayer.entities.add(labelEntity)
            this.labelEntities.set(pkid, labelEntity)
          })
          break
        default:
          break
      }
    },
    onDialogClose() {
      drawnEntity = null
      this.$refs.formRef.resetFields()
      this.selectedMark = null
      this.currentMode = ''
    },
    // Cartesian3转经纬度
    cartesian3ToLatLng(cartesian3) {
      const cartographic =
        Cesium.Cartographic.fromCartesian(cartesian3)
      const longitude = Cesium.Math.toDegrees(
        cartographic.longitude
      )
      const latitude = Cesium.Math.toDegrees(
        cartographic.latitude
      )
      const height = cartographic.height
      return [longitude, latitude, height]
    },
    onSearchChange(val) {
      this.keyword = val
    },
    pageChange(page) {
      this.pageIndex = page
      this.getMarkerList()
    }
  },
  watch: {
    keyword(val) {
      this.pageChange(1)
    },
    typeName(val) {
      this.getMarkerList(false)
    },
    currentMode(val) {
      mark[this.viewerId].changeMode(val, this)
      switch (val) {
        case 'dian':
          this.currentModeName = '点'
          break
        case 'xian':
          this.currentModeName = '线'
          break
        case 'mian':
          this.currentModeName = '面'
          break
        default:
          this.currentModeName = ''
          break
      }
    }
  },
  computed: {
    dialogTitle() {
      let title = ''
      title += this.isNew ? '新增' : '编辑'
      title += this.currentModeName
      return title
    }
  }
}
</script>

<style scoped lang="scss">
.mark {
  height: 680px;
  width: 240px;
  display: flex;
  flex-direction: column;
  //padding: 12px;

  &-draw {
    display: flex;
    justify-content: space-between;
    align-items: center;
    //border-top: 1px solid rgba(255, 255, 255, 0.2);
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    padding: 12px;

    &-item {
      display: flex;
      align-items: center;
      cursor: pointer;

      & > span {
        font-size: 14px;
        font-weight: 400;
        color: #ffffff;
        margin-left: 3px;

        &.active {
          color: #00baff;
        }
      }
    }
  }

  &-list {
    overflow: hidden;
    display: flex;
    flex-direction: column;

    &-item + &-item {
      margin-top: 12px;
    }

    &-item {
      position: relative;
      background-color: #1e425a;
      border-radius: 2px;
      padding: 14px;
      cursor: pointer;
      display: flex;
      flex-direction: column;

      .el-image {
        position: absolute;
        top: 5px;
        right: 5px;
        width: 16px;
        height: 16px;
        cursor: pointer;
      }

      &-head {
        display: flex;
        align-items: center;

        & > span {
          font-size: 14px;
          font-weight: 400;
          color: #ffffff;
          margin-left: 3px;
        }
      }

      .description {
        font-size: 14px;
        font-weight: 500;
        color: #d2e6f0;
        margin-top: 10px;
      }
    }
  }

  ::v-deep {
    .el-pagination {
      margin-bottom: 10px;

      button {
        background: transparent;
        color: white;

        &:disabled {
          &:hover {
            color: white;
          }
        }

        &:hover {
          color: #00d2ff;
        }
      }

      li {
        background-color: transparent;
        color: white;

        &.active {
          color: #00d2ff;
        }
      }
    }
  }
}

::v-deep {
  .el-scrollbar__wrap {
    overflow-x: hidden;
    padding: 12px 10px;
  }
}
</style>
